/*
 *    This file is part of CeluMap.
 *
 *    CeluMap is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    CeluMap is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Copyright 2006, 2007, 2008 Gonzalo Merayo
 *    gonzalo (at) celumap.com.ar
 *    www.celumap.com.ar
 *
 */

package font;

import screen.GisGraphics;

public class Font {
	final static int[] sqrtTable = {0,16,6,5,5,3,4,3,3,3,2,3,2,2,2,2,3,1,2,2,2,2,2,1,2,2,1,2,1,2,1,2,1,1,2,1,2,1,
								1,1,2,1,1,1,2,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,1,1,1,1,1,1,
							1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,1,0,1,1,1,
						0,1,1,1,0,1,1,0,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,0,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,
						1,0,1,0,1,1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,0,
				1,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,
			1,0,1,0,1};
	final static int FIRST_PRINTABLE = 33;
	final static int LAST_PRINTABLE = 126;
//	cat a|sed "s/'/@/g"|awk -F'@' '{print "{{\"" $2 "\"," $6 "},"  $8 "},"};'|sed 's/\([ML]\)\([0-9]*\) \([0-9]*\)/{\"\1\",\2,\3},/g'|sed 's/\([HV]\)\([0-9]*\)/{\"\1\",\2},/g'|sed 's/[Z]/{\"Z\"},/g'|sed "s/\"/\'/g"
	final static byte[][] gliphs = {
		{1,'M',1,3,'V',9,'M',1,1,'V',1,},//	33 !
		{1,'M',1,6,'V',9,'M',2,6,'V',9,},//	34 "
		{5,'M',1,1,'L',3,9,'M',3,1,'L',6,9,'M',1,6,'H',6,'M',1,4,'H',6,},//	35 #
		{4,'M',1,2,'V',3,'L',2,2,'H',4,'L',5,3,'V',4,'L',4,5,'H',2,'L',1,6,'V',7,'L',2,8,'H',4,'L',5,7,'V',8,'M',3,2,'V',1,'M',3,8,'V',9,},//	36 $
		{6,'M',1,2,'L',7,8,'M',2,6,'L',1,7,'L',2,8,'L',3,7,'L',2,6,'M',6,2,'L',5,3,'L',6,4,'L',7,3,'L',6,2,},//	37 %
		{6,'M',7,1,'L',1,7,'V',8,'L',2,9,'H',4,'L',5,8,'V',7,'L',1,3,'V',2,'L',2,1,'H',5,'L',7,3,'V',4,},//	38 &
		{5, },//	39 '
		{2,'M',3,1,'L',2,2,'L',1,4,'V',6,'L',2,8,'L',3,9,},//	40 (
		{2,'M',1,1,'L',2,2,'L',3,4,'V',6,'L',2,8,'L',1,9,},//	41 )
		{4,'M',1,5,'L',3,7,'L',5,5,'M',1,7,'H',5,'M',3,7,'V',9,},//	42 *
		{4,'M',1,5,'H',5,'M',3,3,'V',7,},//	43 +
		{2,'M',1,0,'L',3,2,},//	44 ,
		{4,'M',1,5,'H',5,},//	45 -
		{1,'M',1,1,'V',2,'H',2,'V',1,'Z',},//	46 .
		{5,'M',1,1,'L',6,9,},//	47 /
		{6,'M',1,3,'V',7,'L',3,9,'H',5,'L',7,7,'V',3,'L',5,1,'H',3,'Z',},//	48 0
		{4,'M',1,1,'H',5,'M',3,1,'V',9,'L',1,7,},//	49 1
		{4,'M',1,7,'V',8,'L',2,9,'H',4,'L',5,8,'V',6,'L',1,2,'V',1,'H',5,'V',2,},//	50 2
		{4,'M',1,3,'V',2,'L',2,1,'H',4,'L',5,2,'V',4,'L',4,5,'L',5,6,'V',8,'L',4,9,'H',2,'L',1,8,'V',7,'M',4,5,'H',2,},//	51 3
		{4,'M',3,1,'H',5,'M',4,1,'V',9,'L',1,4,'H',5,},//	52 4
		{4,'M',1,3,'V',2,'L',2,1,'H',4,'L',5,2,'V',4,'L',4,5,'H',1,'V',9,'H',5,},//	53 5
		{4,'M',5,8,'L',4,9,'H',2,'L',1,8,'V',2,'L',2,1,'H',4,'L',5,2,'V',4,'L',4,5,'H',2,'L',1,4,},//	54 6
		{4,'M',1,1,'L',5,9,'H',1,'M',1,5,'H',4,},//	55 7
		{4,'M',2,1,'L',1,2,'V',4,'L',2,5,'L',1,6,'V',8,'L',2,9,'H',4,'L',5,8,'V',6,'L',4,5,'L',5,4,'V',2,'L',4,1,'H',2,'M',2,5,'H',4,},//	56 8
		{4,'M',1,2,'L',2,1,'H',4,'L',5,2,'V',8,'L',4,9,'H',2,'L',1,8,'V',6,'L',2,5,'H',4,'L',5,6,},//	57 9
		{1,'M',1,1,'H',2,'V',2,'H',1,'Z','M',1,4,'V',5,'H',2,'V',4,'Z',},//	58 :
		{1,'M',1,0,'V',2,'H',2,'Z','M',1,4,'V',5,'H',2,'V',4,'Z',},	//	59 ;
		{4,'M',5,1,'L',1,5,'L',5,9,},//	60 <
		{4,'M',1,3,'H',5,'M',1,5,'H',5,},//	61 =
		{4,'M',1,1,'L',5,5,'L',1,9,},//	62 >
		{6,'M',1,6,'V',7,'L',3,9,'H',5,'L',7,7,'V',5,'L',5,3,'H',3,'V',1,'M',3,0,'V',0,},//	63 ?
		{8},//	64 @
		{8,'M',1,1,'L',5,9,'L',9,1,'M',3,5,'H',7,},//	65 A
		{6,'M',1,9,'H',4,'L',6,8,'V',6,'L',4,5,'H',1,'Z','M',1,5,'V',1,'H',5,'L',7,2,'V',4,'L',5,5,'H',4,},//	66 B
		{8,'M',9,8,'L',7,9,'H',4,'L',2,8,'L',1,6,'V',4,'L',2,2,'L',4,1,'H',7,'L',9,2,},//	67 C
		{7,'M',1,9,'V',1,'H',5,'L',7,2,'L',8,4,'V',6,'L',7,8,'L',5,9,'Z',},//	68 D
		{5,'M',6,8,'V',9,'H',1,'V',1,'H',6,'V',2,'M',1,5,'H',4,'M',4,6,'V',4,},//	69 E
		{6,'M',1,9,'H',7,'V',8,'M',2,9,'V',1,'M',1,1,'H',3,'M',2,5,'H',5,'M',5,6,'V',4,},//	70 F
		{8,'M',3,5,'H',9,'M',8,5,'L',9,4,'V',3,'L',8,2,'L',6,1,'H',4,'L',2,2,'L',1,3,'V',6,'L',2,8,'L',4,9,'H',7,'L',9,8,'V',7,},//	71 G
		{8,'M',1,9,'H',3,'M',2,9,'V',1,'M',1,1,'H',3,'M',2,5,'H',8,'M',7,9,'H',9,'M',8,9,'V',1,'M',7,1,'H',9,},//	72 H
		{6,'M',1,9,'H',7,'M',4,9,'V',1,'M',1,1,'H',7,},//	73 I
		{6,'M',1,4,'V',3,'L',3,1,'H',4,'L',6,3,'V',9,'M',7,9,'H',3,},//	74 J
		{6,'M',1,9,'H',3,'M',2,9,'V',1,'M',1,1,'H',3,'M',2,4,'L',6,9,'M',5,9,'H',7,'M',3,5,'L',6,1,'M',5,1,'H',7,},//	75 K
		{5,'M',1,9,'H',3,'M',2,9,'V',1,'M',1,1,'H',6,'V',2,},//	76 L
		{8,'M',1,9,'H',3,'L',5,5,'L',7,9,'H',9,'M',8,9,'V',1,'M',7,1,'H',9,'M',2,9,'V',1,'M',1,1,'H',3,},//	77 M
		{8,'M',1,9,'H',3,'L',7,1,'H',9,'M',8,1,'V',9,'M',7,9,'H',9,'M',2,9,'V',1,'M',1,1,'H',3,},//	78 N
		{8,'M',1,4,'L',2,2,'L',4,1,'H',6,'L',8,2,'L',9,4,'V',6,'L',8,8,'L',6,9,'H',4,'L',2,8,'L',1,6,'Z',},//	79 O
		{7,'M',1,9,'H',6,'L',8,8,'V',6,'L',6,5,'H',2,'M',2,9,'V',1,'M',1,1,'H',4,},//	80 P
		{8,'M',1,4,'L',2,2,'L',4,1,'H',6,'L',8,2,'L',9,4,'V',6,'L',8,8,'L',6,9,'H',4,'L',2,8,'L',1,6,'Z','M',3,0,'L',4,1,'M',6,1,'L',8,0,'L',9,1,},//	81 Q
		{8,'M',1,9,'H',6,'L',8,8,'V',6,'L',6,5,'H',2,'M',2,9,'V',1,'M',1,1,'H',4,'M',6,5,'L',8,1,'M',7,1,'H',9,},//	82 R
		{6,'M',1,1,'V',3,'M',1,2,'L',3,1,'H',5,'L',7,2,'V',4,'L',5,5,'H',3,'L',1,6,'V',8,'L',3,9,'H',5,'L',7,8,'M',7,9,'V',7,},//	83 S
		{6,'M',1,7,'V',9,'H',7,'V',7,'M',4,9,'V',1,'M',3,1,'H',5,},//	84 T
		{8,'M',1,9,'H',3,'M',2,9,'V',4,'L',3,2,'L',4,1,'H',6,'L',7,2,'L',8,4,'V',9,'M',7,9,'H',9,},//	85 U
		{8,'M',1,9,'H',3,'M',2,9,'L',5,1,'L',8,9,'M',7,9,'H',9,},//	86 V
		{8,'M',1,9,'H',3,'M',2,9,'V',2,'L',3,1,'H',4,'L',5,5,'L',6,1,'H',7,'L',8,2,'V',9,'M',7,9,'H',9,},//	87 W
		{7,'M',1,9,'H',3,'M',2,9,'L',7,1,'M',6,1,'H',8,'M',1,1,'H',3,'M',2,1,'L',7,9,'M',6,9,'H',8,},//	88 X
		{8,'M',1,9,'H',3,'M',2,9,'L',5,5,'L',8,9,'M',7,9,'H',9,'M',5,5,'V',1,'M',4,1,'H',6,},//	89 Y
		{6,'M',1,8,'V',9,'H',7,'L',1,1,'H',7,'V',2,'M',2,5,'H',6,},	//	90 Z	
		{1,'M',2,9,'H',1,'V',1,'H',2,},//	91 [
		{6,'M',1,9,'L',7,1,},//	92 \
		{1,'M',1,9,'H',2,'V',1,'H',1,},//	93 ]
		{4,'M',1,4,'L',3,6,'L',5,4,},//	94 ^
		{6,'M',1,1,'H',7,},//	95 _
		{1,'M',1,6,'L',2,5,},//	96 `
		{7,'M',1,6,'L',2,7,'H',6,'L',7,6,'V',2,'L',8,1,'M',7,4,'L',6,5,'H',2,'L',1,4,'V',2,'L',2,1,'H',6,'L',7,2,},//	97 a
		{7,'M',1,10,'H',2,'V',1,'H',1,'M',2,6,'L',3,7,'H',6,'L',8,5,'V',3,'L',6,1,'H',3,'L',2,2,},//	98 b
		{6,'M',7,5,'V',6,'L',5,7,'H',3,'L',1,5,'V',3,'L',3,1,'H',5,'L',7,2,'V',3,},//	99 c
		{7,'M',8,10,'H',7,'V',1,'H',8,'M',7,6,'L',6,7,'H',3,'L',1,5,'V',3,'L',3,1,'H',6,'L',7,2},//	100 d
		{7,'M',1,5,'L',3,7,'H',6,'L',8,5,'Z','M',1,5,'V',3,'L',3,1,'H',6,'L',8,3,},//	101 e
		{4,'M',1,1,'H',3,'M',2,1,'V',7,'L',3,9,'H',4,'L',5,8,'M',1,5,'H',4,},//	102 f
		{7,'M',1,1,'L',2,0,'H',6,'L',7,1,'V',7,'H',8,'M',7,5,'L',5,7,'H',3,'L',1,5,'V',3,'L',3,1,'H',5,'L',7,3,},//	103 g
		{5,'M',1,10,'H',2,'V',1,'M',2,5,'L',3,7,'H',5,'L',6,5,'V',1,},//	104 h
		{3,'M',1,7,'H',2,'V',1,'M',1,1,'H',3,'M',2,8,'V',8,},//	105 i
		{3,'M',1,2,'L',2,0,'H',3,'L',4,2,'V',7,'H',1,'M',3,8,'V',8,},//	106 j
		{5,'M',1,7,'H',2,'V',1,'M',2,3,'L',5,7,'H',6,'M',3,4,'L',5,1,'M',4,1,'H',6,},//	107 k
		{2,'M',1,10,'H',2,'V',1,'M',1,1,'H',3,},//	108 l
		{8,'M',1,7,'H',2,'V',1,'H',3,'M',2,6,'L',3,7,'H',4,'L',5,6,'L',6,7,'H',7,'L',8,6,'V',1,'H',9,'M',5,6,'V',1,'H',6,},//	109 m
		{5,'M',1,7,'H',2,'V',1,'H',3,'M',2,6,'L',3,7,'H',4,'L',5,6,'V',1,'H',6,},//	110 n
		{6,'M',1,3,'V',5,'L',3,7,'H',5,'L',7,5,'V',3,'L',5,1,'H',3,'Z',},//	111 o
		{7,'M',1,7,'H',2,'V',0,'M',1,0,'H',3,'M',2,2,'L',3,1,'H',6,'L',8,3,'V',5,'L',6,7,'H',3,'L',2,6,},//	112 p
		{7,'M',8,7,'H',7,'V',0,'M',8,0,'H',6,'M',7,6,'L',6,7,'H',3,'L',1,5,'V',3,'L',3,1,'H',6,'L',7,2,},//	113 q
		{4,'M',1,7,'H',2,'V',1,'H',3,'M',2,6,'L',3,7,'H',4,'L',5,6,},//	114 r
		{4,'M',1,1,'V',2,'L',2,1,'H',4,'L',5,2,'V',3,'L',4,4,'H',2,'L',1,5,'V',6,'L',2,7,'H',4,'L',5,6,'V',7,},//	115 s
		{4,'M',1,7,'H',5,'M',2,10,'V',2,'L',3,1,'H',4,'L',5,2,},//	116 t
		{6,'M',1,7,'H',2,'V',2,'L',3,1,'H',5,'L',6,2,'V',7,'H',5,'M',6,2,'L',7,1,},//	117 u
		{6,'M',1,7,'H',2,'L',4,1,'L',6,7,'H',7,},//	118 v
		{8,'M',1,7,'H',2,'L',4,1,'L',5,3,'L',6,1,'L',8,7,'H',9,},//	119 w
		{6,'M',1,7,'H',2,'L',6,1,'H',7,'M',1,1,'L',6,7,'H',7,},//	120 x
		{6,'M',1,7,'H',2,'L',4,3,'M',1,0,'H',3,'L',6,7,'H',7,},//	121 y
		{5,'M',1,6,'V',7,'H',6,'L',1,1,'H',6,'V',2,},//	122 z
		{2,'M',3,9,'L',2,8,'V',6,'L',1,5,'L',2,4,'V',2,'L',3,1,},//	123 {
		{1,'M',1,9,'V',1,},//	124 |
		{2,'M',1,9,'L',2,8,'V',6,'L',3,5,'L',2,4,'V',2,'L',1,1,},//	125 }
		{3,'M',1,3,'L',2,4,'L',3,3,'L',4,4,},//	126 ~
		};

	public Font(){
		for(int i=1;i<sqrtTable.length;i++)
			sqrtTable[i] += sqrtTable[i-1]; 
	}
	
	public void setFgColor(int c) {
		// TODO Auto-generated method stub
		
	}

	public void drawString(byte[] b, GisGraphics g, int xi, int yi, int dx, int dy){
		if(dx==0&&dy==0)
			dx=10;
		int dist = fastSqrt(dx*dx+dy*dy);
		xi += (2*(dy+dx))/dist;
		yi += (2*(dy-dx))/dist;
		
		for(int i=0;i<b.length && b[i]!=0;i++){
			if(b[i]==' '){
				xi += ((8)*dx)/dist;
				yi += ((8)*dy)/dist;
			}else{
				if(b[i]>LAST_PRINTABLE || b[i]<FIRST_PRINTABLE)
					continue;
				int j=b[i]-FIRST_PRINTABLE;
				drawGliph(gliphs[j], xi, yi, g, dx, dy, dist);
				xi += ((gliphs[j][0]+4)*dx)/dist;
				yi += ((gliphs[j][0]+4)*dy)/dist;
			}
		}
	}
	
	static int cpx, cpy, spx, spy, dpx, dpy;
	private final void drawGliph(byte[] P, int xi, int yi, GisGraphics g, int dx, int dy, int dist){
		cpx = 0; cpy= 0;
		spx = 0; spy= 0;
		dpx = 0; dpy= 0;
		for(int i=1; i<P.length; i++){
			switch(P[i]){
				case 'M'://move
					cpx = spx = dpx = P[++i];
					cpy = spy = dpy = - P[++i];
					continue;
				case 'L'://line
					dpx = P[++i];
					dpy = - P[++i];
					break;
				case 'H'://horizontal
					dpx = P[++i];
					break;
				case 'V'://vertigal
					dpy = - P[++i];
					break;
				case 'Z'://origen
					dpx = spx;
					dpy = spy;
			}
			g.drawLine(xi+(cpx*dx-cpy*dy)/dist,
			yi+(cpx*dy+cpy*dx)/dist,
			xi+(dpx*dx-dpy*dy)/dist,
			yi+(dpx*dy+dpy*dx)/dist);
			cpx = dpx;
			cpy = dpy;
		}
	}

	static int fastSqrt(int x) {
	    if (x >= 0x10000) {
	      if (x >= 0x1000000) {
	        if (x >= 0x10000000) {
	          if (x >= 0x40000000) {
	            return (sqrtTable[x >> 24] << 8);
	          } else {
	            return (sqrtTable[x >> 22] << 7);
	          }
	        } else if (x >= 0x4000000) {
	          return (sqrtTable[x >> 20] << 6);
	        } else {
	          return (sqrtTable[x >> 18] << 5);
	        }
	      } else if (x >= 0x100000) {
	        if (x >= 0x400000) {
	          return (sqrtTable[x >> 16] << 4);
	        } else {
	          return (sqrtTable[x >> 14] << 3);
	        }
	      } else if (x >= 0x40000) {
	        return (sqrtTable[x >> 12] << 2);
	      } else {
	        return (sqrtTable[x >> 10] << 1);
	      }
	    } else if (x >= 0x100) {
	      if (x >= 0x1000) {
	        if (x >= 0x4000) {
	          return (sqrtTable[x >> 8]);
	        } else {
	          return (sqrtTable[x >> 6] >> 1);
	        }
	      } else if (x >= 0x400) {
	        return (sqrtTable[x >> 4] >> 2);
	      } else {
	        return (sqrtTable[x >> 2] >> 3);
	      }
	    } else if (x >= 0) {
	      return sqrtTable[x] >> 4;
	    }
	    return -1;
	  }
}
